

package com.eibus.applicationconnector.dotnet;

import junit.framework.TestCase;
import com.eibus.connector.nom.Connector;
import com.eibus.xml.nom.Node;
import com.eibus.xml.xpath.XPath;

import java.util.Hashtable;


//@Author	: Lejil
//@Class	: DotnetMetadataTest

/**
 *	<br/>Owner:			Lejil
 *	<br/>Description:	Invoke the .NET MetaData Methods for default values, different combinations of types etc.. 
 */
public class DotnetMetadataTestCase extends TestCase
{
	Connector  connector ;
	private final String className			=	"UnitTest.UnitTestMethods";
	private final String refClassName		=	"UnitTest.RefArguments";
	private final String staticRefClassName =	"UnitTest.StaticRefArguments";
	private final String staticClassName	=	"UnitTest.StaticUnitTest";
	private final String assemblyName		=	"UnitTest, Version=2.0.0.0, Culture=neutral, PublicKeyToken=e25a327e965279f3";

	private final String isStatic			=	"false";
	private final String namesapce			=	"http://schemas.cordys.com/1.0/metadata/dotnet";



	protected void setUp()
	{
		try
		{
			connector = Connector.getInstance("DotNET Client");
			if (!connector.isOpen())
				connector.open();
		}
		catch(Exception exception)
		{
			fail("Could not get instance of Connector. "+exception.getMessage());
		}
	}


	protected void tearDown()
	{

	}

	public DotnetMetadataTestCase(String name)
	{
		super(name);
	}

	public static void main(String[] args)
	{
		junit.textui.TestRunner.run(DotnetMetadataTestCase.class);
	}


	public  boolean checkforSoapFault(int response) throws Exception
	{
		
		try
		{
			int  faultNode = XPathUtil.getSOAPFault(response);

			if ( faultNode != 0)
			{
				fail(".NET Connector junit Method Failed with SoapFault	:-"+Node.writeToString(faultNode,true));
			}
		}
		catch(Exception ex)
		{
			throw ex;
		}
		return true;
	}


	public void testMetadataGetAllStaticMethods() //1
	{
		int response =0,request =0;
		try
		{
			request 	= connector.createSOAPMethod(namesapce,"GetAllMethods");
			Node.createTextElement("assembly",assemblyName,request);
			Node.createTextElement("class",staticClassName,request);
			Node.createTextElement("isStatic",isStatic,request);
			response = connector.sendAndWait(Node.getParent(request));
			checkforSoapFault(response);
			checkAllMethods(response);

		}
		catch(Exception ex)
		{
			fail ("GetAllStaticMethods failed with excption" + ex.toString());
		}
		finally
		{
			Util.delete(Node.getRoot(response));
			Util.delete(Node.getRoot(request));

		}

	}

	public void testMetadataGetAllInstanceMethods() //2
	{
		int response = 0,request =0;
		try
		{
			request 	= connector.createSOAPMethod(namesapce,"GetAllMethods");
			Node.createTextElement("assembly",assemblyName,request);
			Node.createTextElement("class",className,request);
			Node.createTextElement("isStatic",isStatic,request);
			response = connector.sendAndWait(Node.getParent(request));
			checkforSoapFault(response);
			checkAllMethods(response);
		}
		catch(Exception ex)
		{
		  fail("testMetadataGetAllInstanceMethods failed with exception");
		}
		finally
		{
			Util.delete(Node.getRoot(response));
			Util.delete(Node.getRoot(request));
		}
	}


	public void testMetadataGetAllRefMethods() //3
	{
		int response =	0 ,request =0;
		try
		{
			request 	= connector.createSOAPMethod(namesapce,"GetAllMethods");
			Node.createTextElement("assembly",assemblyName,request);
			Node.createTextElement("class",refClassName,request);
			Node.createTextElement("isStatic",isStatic,request);
			response = connector.sendAndWait(Node.getParent(request));
			checkforSoapFault(response);
			checkAllMethods(response);
		}
		catch(Exception ex)
		{
			 fail("testMetadataGetAllRefMethods failed with exception");
		}
		finally
		{
			Util.delete(Node.getRoot(response));
			Util.delete(Node.getRoot(request));

		}
	}

	public void testMetadataGetAllRefStaticMethods() //4
	{
		int response = 0,request =0;
		try
		{
			request 	= connector.createSOAPMethod(namesapce,"GetAllMethods");
			Node.createTextElement("assembly",assemblyName,request);
			Node.createTextElement("class",staticRefClassName,request);
			Node.createTextElement("isStatic",isStatic,request);
			response = connector.sendAndWait(Node.getParent(request));
			checkforSoapFault(response);
			checkAllMethods(response);
		}
		catch(Exception ex)
		{
			 fail("testMetadataGetAllRefStaticMethods failed with exception");
		}
		finally
		{
			Util.delete(Node.getRoot(response));
			Util.delete(Node.getRoot(request));
		}
	}

	private void checkAllMethods(int response)
	{
		//int[] methods = Find.match(response,"?<methods><method>");
        int[] methods = new XPath(".//methods/method").selectElementNodes(response);
		Hashtable  methodsTable =new Hashtable();
		int counter = 0;
        XPath nameXPath = new XPath(".//name");
        XPath returntypeXPath = new XPath(".//returntype");
        XPath parameterXPath = new XPath(".//parameters/parameter");
        
		for (int i=0;i < methods.length ; i++ )
		{
			//String methodName =  Find.firstDataWithDefault(methods[i],"?<name>","NotFound");
			//String returnType =  Find.firstDataWithDefault(methods[i],"?<returntype>","NotFound");
			//int[] parameters  =  Find.match(methods[i],"?<parameters><parameter>");
            String methodName = Node.getDataWithDefault(
                    nameXPath.firstMatch(methods[i], null), "NotFound");
            String returnType = Node.getDataWithDefault(
                    returntypeXPath.firstMatch(methods[i], null), "NotFound");
            int[] parameters = parameterXPath.selectElementNodes(methods[i]);
            
			if (methodsTable.contains(methodName))
			{
				fail("Metadata Method Failed,same Entry is added more than once");
			}
			methodsTable.put(methodName,returnType);

			if (methodName.equals("TestBoolType")||methodName.equals("TestStaticBoolType") )
			{
				if (!returnType.equals("boolean"))
					fail("Retun type expected is boolean ,but returned "+returnType);
				if (parameters.length != 2)
					fail("Expected method arguments are two,but returned different");
				counter++;
			}
			else if(methodName.equals("TestByteType") ||methodName.equals("TestStaticByteType"))
			{
				if (!returnType.equals("i1"))
					fail("Return type expected is i1 ,but returned "+returnType);
				if (parameters.length != 2)
					fail("Expected method arguments are two,but returned different");
				counter++;
			}
			else if(methodName.equals("TestCharType")||methodName.equals("TestStaticCharType"))
			{
				if (!returnType.equals("char"))
					fail("Return type expected is char ,but returned "+returnType);
				if (parameters.length != 2)
					fail("Expected method arguments are two,but returned different");
				counter++;
			}
			else  if(methodName.equals("TestDoubleType")||methodName.equals("TestStaticDoubleType"))
			{
				if (!returnType.equals("r8"))
					fail("Return type expected is r8 ,but returned "+returnType);
				if (parameters.length != 2)
					fail("Expected method arguments are two,but returned different");
				counter++;
			}
			else if(methodName.equals("TestIntegerType") || methodName.equals("TestStaticIntegerType"))
			{
				if (!returnType.equals("i4"))
					fail("Return type expected is i4 ,but returned "+returnType);
				if (parameters.length != 2)
					fail("Expected method arguments are two,but returned "+returnType);
				counter++;
			}
			else  if(methodName.equals("TestLongType") || methodName.equals("TestStaticLongType"))
			{
				if (!returnType.equals("i8"))
					fail("Retun type expected is i8 ,but returned "+returnType);
				if (parameters.length != 2)
					fail("Expected method arguments are two,but returned different");
				counter++;
			}
			else  if(methodName.equals("TestShortType") || methodName.equals("TestStaticShortType"))
			{
				if (!returnType.equals("i2"))
					fail("Return type expected is i2 ,but returned different");
				if (parameters.length != 2)
					fail("Expected method arguments are two,but returned "+returnType);
				counter++;
			}
			else if(methodName.equals("TestSingleType") || methodName.equals("TestStaticSingleType"))
			{
				if (!returnType.equals("r4"))
					fail("Return type expected is r4 ,but returned "+returnType);
				if (parameters.length != 2)
					fail("Expected method arguments are two,but returned different");
				counter++;
			}
			else if(methodName.equals("TestStringType") || methodName.equals("TestStaticStringType"))
			{
				if (!returnType.equals("string"))
					fail("Return type expected is string ,but returned "+returnType);
				if (parameters.length != 2)
					fail("Expected method arguments are two,but returned different");
				counter++;
			}
			else if(methodName.equals("TestXmlType") || methodName.equals("TestStaticXmlType"))
			{
				if (!returnType.equals("xml"))
					fail("Return type expected is xml ,but returned different");
				if (parameters.length != 2)
					fail("Expected method arguments are two,but returned "+returnType);
				counter++;
			}
			else if(methodName.equals("TestDateTimeType") || methodName.equals("TestStaticDateTimeType"))
			{
				if (!returnType.equalsIgnoreCase("dateTime"))
					fail("Return type expected is datetime ,but returned "+returnType);
				if (parameters.length != 2)
					fail("Expected method arguments are two,but returned different");
				counter++;
			}
			else if(methodName.equals("TestXMLNomType")|| methodName.equals("TestStaticXMLNomType"))
			{
				if (!returnType.equals("i4"))
					fail("Retun type expected is i4 ,but returned "+returnType);
				if (parameters.length != 2)
					fail("Expected method arguments are two,but returned different");
				counter++;
			}

		}
		if ( counter != 12 )
		{
			fail ("Expected 12 Methods , but returned " + counter);
		}
	}
 	/*
	public void testMetadataGetAllNamespaceFromAbsolutepath() //6
	{
		int response = 0,request =0;
		String cordy_install_dir =EIBProperties.getInstallDir();
		String assemblyLocation =cordy_install_dir+"\\WCP\\bin\\UnitTest.dll";
		try
		{
			request = connector.createSOAPMethod(namesapce,"GetAllClassesAndNamespace");
			Node.createTextElement("assembly",assemblyLocation,request);
			Node.createTextElement("namespace","",request);
			response = connector.sendAndWait(Node.getParent(request));
			String assembly = Find.firstDataWithDefault(response,"?<assembly><name>","Connector");
			if (! assembly.equalsIgnoreCase(assemblyName) )
				fail ("testMetadataGetAllNamespaceFromAbsolutepath expected  value is"+assemblyName +"but returned"+ assembly);


		}
		catch(Exception ex)
		{
			fail("testMetadataGetAllNamespaceFromAbsolutepath failed with exception");
		}
		finally
		{
			Node.delete(Node.getRoot(response));
			Node.delete(Node.getRoot(request));
		}
	}
*/

	public void testMetadataGetAllNamespace() //6
	{
		int response = 0,request =0;
		try
		{
			request = connector.createSOAPMethod(namesapce,"GetAllClassesAndNamespace");
			Node.createTextElement("assembly",assemblyName,request);
			Node.createTextElement("namespace","",request);
			response = connector.sendAndWait(Node.getParent(request));
			//String assembly = Find.firstDataWithDefault(response,"?<assembly><name>","Connector");
            String assembly = Node.getDataWithDefault(
                    new XPath(".//assembly/name").firstMatch(response, null), "Not Found");
			if (! assembly.equals(assemblyName) )
				fail ("testMetadataGetAllNamespace expected  value is"+assemblyName +"but returned"+ assembly);


		}
		catch(Exception ex)
		{
			fail("testMetadataGetAllNamespace failed with exception");
		}
		finally
		{
			Util.delete(Node.getRoot(response));
			Util.delete(Node.getRoot(request));
		}
	}

	public void testMetadataGetAllNamespaceWithNamespace() //6
	{
		int response = 0,request =0;
		try
		{
			request = connector.createSOAPMethod(namesapce,"GetAllClassesAndNamespace");
			Node.createTextElement("assembly",assemblyName,request);
			Node.createTextElement("namespace","UnitTest.",request);
			response = connector.sendAndWait(Node.getParent(request));
			//String assembly = Find.firstDataWithDefault(response,"?<assembly><name>","Connector");
             String assembly = Node.getDataWithDefault(
                        new XPath(".//assembly/name").firstMatch(response, null), "Not Found");
			if (! assembly.equals(assemblyName) )
				fail ("testMetadataGetAllNamespaceWithNamespace expected  value is"+assemblyName +"but returned"+ assembly);


		}
		catch(Exception ex)
		{
			fail("testMetadataGetAllNamespaceWithNamespace failed with exception");
		}
		finally
		{
			Util.delete(Node.getRoot(response));
			Util.delete(Node.getRoot(request));
		}
	}


	public void testMetadataGetAllClassesAndNamespace() //7
	{
		int response = 0,request =0;
		String methodName ="GetAllClassesAndNamespace";
		try
		{
			request = connector.createSOAPMethod(namesapce,methodName);
			Node.createTextElement("assembly",assemblyName,request);
			Node.createTextElement("namespace","",request);
			response = connector.sendAndWait(Node.getParent(request));
			//String className = Find.firstDataWithDefault(response,"?<classes><class><name>","Connector");
            String className = Node.getDataWithDefault(
                        new XPath(".//classes/class/name").firstMatch(response, null), "Not Found");
			if (! className.equals("UnitTest.") )
				fail ("testMetadataGetAllClassesAndNamespace expected UnitTest methods but returned "+className);


		}
		catch(Exception ex)
		{
			fail("testMetadataGetAllClassesAndNamespace failed with exception");
		}
		finally
		{
			Util.delete(Node.getRoot(response));
			Util.delete(Node.getRoot(request));
		}

	}



	public void testMetadataForDefaultValues() //8
	{
		int response = 0,request =0;
		String assemblyName="jTest, Version=2.0.0.0, Culture=neutral, PublicKeyToken=e25a327e965279f3";
		boolean isValueExist =false;
		try
		{
			request = connector.createSOAPMethod(namesapce,"GetAllMethods");
			Node.createTextElement("assembly",assemblyName,request);
			Node.createTextElement("namespace","jTest.UnitTest",request);
			Node.createTextElement("isStatic","false",request);

			response = connector.sendAndWait(Node.getParent(request));
            XPath datatypeXPath = new XPath(".//parameter/datatype");
            //int[]  methods =  Find.match(response,"?<method>");
            int[] methods = new XPath(".//method").selectElementNodes(response);
			for (int i=0; i<methods.length ;i++)
			{
				//String methodName =Find.firstDataWithDefault(methods[i],"?<method><name>","fail");
                String methodName = Node.getDataWithDefault(Node.getElement(methods[i], "name"), "fail");
                
				if (methodName.equalsIgnoreCase("defaultByRefArgs"))
				{
					//int dataTypeNode =Find.firstMatch(methods[i],"?<parameter><datatype>");
                    int dataTypeNode = datatypeXPath.firstMatch(methods[i], null);
					String defaultValue = Node.getAttribute(dataTypeNode,"defaultValue","fail");
					if (!defaultValue.equalsIgnoreCase("Cordys India"))
					{
						fail("Expected defalutValue is Cordys India, but returned" +defaultValue);
					}

					String typeAttribute = Node.getAttribute(dataTypeNode,"ct","ByVal");
					if (!typeAttribute.equalsIgnoreCase("ByRef"))
					{
						fail("Expected defalutValue is ByRef, but returnred" +typeAttribute);
					}
					String dataType 	= Node.getData(dataTypeNode,"fail");
					if (!dataType.equalsIgnoreCase("string"))
					{
						fail("Expected defalutValue is string, but returnred" +typeAttribute);
					}

					isValueExist =true;
				}
			}
			if (isValueExist == false)
				fail("Expected defalutValue is Cordys India, but returned different");
		}
		catch(Exception ex)
		{
			fail("testMetadataForDefaultValues failed with exception");
		}
		finally
		{
			Util.delete(Node.getRoot(response));
			Util.delete(Node.getRoot(request));
		}

	}

}
